//
//  UIImage+Function.m
//  KKCategory
//
//  Created by liaozhenming on 16/5/17.
//  Copyright © 2016年 liaozhenming. All rights reserved.
//

#import "UIImage+Function.h"

#import <QuartzCore/QuartzCore.h>
#import <Accelerate/Accelerate.h>

@implementation UIImage (Function)

+ (instancetype)kk_imageWithColor:(UIColor*)color {
    
    CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

+ (instancetype)kk_screenImageWithLayer:(CALayer*)layer {
    
    if (layer == nil) {
        return nil;
    }
    
    CGRect rect = layer.frame;
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [layer renderInContext:context];
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return img;
}

//  缩放图片
- (UIImage*)kk_scaleImageWithZoom:(float)zoom {
    if (self == nil) {
        return nil;
    }
    
    UIGraphicsBeginImageContext(CGSizeMake(self.size.width * zoom, self.size.height * zoom));
    [self drawInRect:CGRectMake(0, 0, self.size.width * zoom, self.size.height * zoom)];
    UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return scaledImage;
}

//  比例裁剪
- (UIImage*)kk_cutOutWithZoom:(float)zoom {
    if (self == nil) {
        return nil;
    }
    
    CGRect cutRect;
    CGFloat orignalHeight = self.size.height;
    CGFloat orignalWidth  = self.size.width;
    
    if (orignalWidth/orignalHeight == zoom) {
        return self;
    }
    else if (orignalWidth/orignalHeight > zoom) {
        cutRect = CGRectMake((orignalWidth-orignalHeight*zoom)/2, 0, orignalHeight*zoom, orignalHeight);
    }
    else{
        
        cutRect = CGRectMake(0, 0, orignalWidth, orignalWidth/zoom);
    }
    return [self kk_cutOutWithFrame: cutRect];
}

//  范围裁剪
- (UIImage*)kk_cutOutWithFrame:(CGRect)frame {
    
    if (self == nil) {
        return nil;
    }
    
    if (CGRectEqualToRect(CGRectMake(0, 0, self.size.width, self.size.height), frame)) {
        return self;
    }
    
    CGRect cutFrame = frame;
    
    CGImageRef imageRef = self.CGImage;
    CGImageRef subImageRef = CGImageCreateWithImageInRect(imageRef, cutFrame);
    UIGraphicsBeginImageContext(cutFrame.size);
    
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextDrawImage(context, cutFrame, subImageRef);
    
    UIImage* smallImage = [UIImage imageWithCGImage:subImageRef];
    UIGraphicsEndImageContext();
    CGImageRelease(subImageRef);
    return smallImage;
}

//  根据切割点来裁剪图片
- (UIImage*)kk_cutOutWithPoints:(NSArray*)points {
    
    if (points.count == 0) {
        return self;
    }
    
    UIGraphicsBeginImageContext(self.size);
    CGContextRef contextRef = UIGraphicsGetCurrentContext();
    
    CGPoint firstPoint = [points[0] CGPointValue];
    CGContextMoveToPoint(contextRef, firstPoint.x, firstPoint.y);
    
    for (NSInteger index = 1; index < points.count; index++) {
        CGPoint point = [points[index] CGPointValue];
        CGContextAddLineToPoint(contextRef, point.x, point.y);
    }
    CGContextClosePath(contextRef);
    CGContextClip(contextRef);
    
    CGContextTranslateCTM(contextRef, 0, self.size.height);
    CGContextScaleCTM(contextRef, 1, -1);
    CGContextDrawImage(contextRef, CGRectMake(0, 0, self.size.width, self.size.height), self.CGImage);
    
    UIImage *cutImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return cutImage;
}

//  模糊效果
- (UIImage*)kk_blurImageWithBlurValue:(float)blur {
    
    if (blur < 0.f || blur > 1.f) {
        blur = 0.5f;
    }
    int boxSize = (int)(blur * 40);
    boxSize = boxSize - (boxSize % 2) + 1;
    
    CGImageRef img = self.CGImage;
    vImage_Buffer inBuffer, outBuffer;
    vImage_Error error;
    void *pixelBuffer;
    
    //create vImage_Buffer with data from CGImageRef
    CGDataProviderRef inProvider = CGImageGetDataProvider(img);
    CFDataRef inBitmapData = CGDataProviderCopyData(inProvider);
    
    inBuffer.width = CGImageGetWidth(img);
    inBuffer.height = CGImageGetHeight(img);
    inBuffer.rowBytes = CGImageGetBytesPerRow(img);
    
    inBuffer.data = (void*)CFDataGetBytePtr(inBitmapData);
    
    //create vImage_Buffer for output
    pixelBuffer = malloc(CGImageGetBytesPerRow(img) * CGImageGetHeight(img));
    
    if(pixelBuffer == NULL)
        NSLog(@"No pixelbuffer");
    
    outBuffer.data = pixelBuffer;
    outBuffer.width = CGImageGetWidth(img);
    outBuffer.height = CGImageGetHeight(img);
    outBuffer.rowBytes = CGImageGetBytesPerRow(img);
    
    //perform convolution
    error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);
    
    if (error) {
        NSLog(@"error from convolution %ld", error);
    }
    
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef ctx = CGBitmapContextCreate(outBuffer.data,
                                             outBuffer.width,
                                             outBuffer.height,
                                             8,
                                             outBuffer.rowBytes,
                                             colorSpace,
                                             CGImageGetBitmapInfo(self.CGImage));
    CGImageRef imageRef = CGBitmapContextCreateImage (ctx);
    UIImage *returnImage = [UIImage imageWithCGImage:imageRef];
    
    //clean up
    CGContextRelease(ctx);
    CGColorSpaceRelease(colorSpace);
    
    free(pixelBuffer);
    CFRelease(inBitmapData);
    
    CGImageRelease(imageRef);
    
    return returnImage;
}

@end
